package com.ramblingcoder.bc2.server.tool.update.objects;

import java.io.IOException;
import java.net.Socket;
import java.text.DecimalFormat;

import com.ramblingcoder.bc2.server.tool.update.commands.Parcel;
import com.ramblingcoder.bc2.server.tool.update.commands.SupportingFunctions;
import com.ramblingcoder.bc2.server.tool.update.exceptions.AccessError;
import com.ramblingcoder.bc2.server.tool.update.exceptions.BanListFull;
import com.ramblingcoder.bc2.server.tool.update.exceptions.InvalidArguments;
import com.ramblingcoder.bc2.server.tool.update.exceptions.LogInRequired;
import com.ramblingcoder.bc2.server.tool.update.exceptions.NotFound;
import com.ramblingcoder.bc2.server.tool.update.exceptions.PlayerNotFound;

public class Ban {
	//Variables-----\
	private String idType;
	private String id;
	private String banType;
	private String duration;
	private String reason;
	//Variables-----/
	
	//Processes-----\
	public static Ban[] listBans(Socket socket) throws IOException, LogInRequired, InvalidArguments {		
		SupportingFunctions.sendCommand(socket.getOutputStream(), new String[]{"banList.list"});
		Parcel[] response = SupportingFunctions.getResponse(socket.getInputStream());
		
		if (response[0].getStatus().equals("OK"))
			return parseBans(response[0]);
		else if (response[0].getStatus().equals("InvalidArguments"))
			throw new InvalidArguments();
		else if (response[0].getStatus().equals("LogInRequired"))
			throw new LogInRequired();
		else
			return null;
	}

	private static Ban[] parseBans(Parcel parcel) {
		String[] words = parcel.getWords();
		
		//0 = OK
		//1 = # of bans
		Ban[] bans = new Ban[Integer.parseInt(words[1])];
		for (int i = 2, count = 0; i < words.length; i+=5, count++){
			Ban ban = new Ban();
			
			System.out.println(words[i]);
			System.out.println(words[i+1]);
			System.out.println(words[i+2]);
			System.out.println(words[i+3]);
			System.out.println(words[i+4]);
			
			ban.setIdType(words[i]);
			ban.setId(words[i+1]);
			ban.setBanType(words[i+2]);
			ban.setDuration(words[i+3]);
			ban.setReason(words[i+4]);
			
			System.out.println(Integer.parseInt(words[1]) + " : " + count);
			bans[count] = ban;
		}
		
		return bans;
	}
	
	//----------------------------------------------------------------------------------------------------

	public static boolean ban(Socket socket, String type, String id, String timeout, String reason) throws IOException, InvalidArguments, BanListFull, LogInRequired{
		if (reason == null)
			SupportingFunctions.sendCommand(socket.getOutputStream(), new String[]{"banList.add", type, id, timeout});
		else if (reason.trim().equals(""))
			SupportingFunctions.sendCommand(socket.getOutputStream(), new String[]{"banList.add", type, id, timeout});
		else 
			SupportingFunctions.sendCommand(socket.getOutputStream(), new String[]{"banList.add", type, id, timeout, reason});
		
		Parcel response = SupportingFunctions.getResponse(socket.getInputStream())[0];
		
		if (response.getStatus().equalsIgnoreCase("ok"))
			return true;
		else if (response.getStatus().equalsIgnoreCase("InvalidArguments"))
			throw new InvalidArguments();
		else if (response.getStatus().equalsIgnoreCase("BanListFull"))
			throw new BanListFull("Ban list is at capacity. Max capacity is 100.");
		else if (response.getStatus().equals("LogInRequired"))
			throw new LogInRequired();
		
		return false;
	}

	public static boolean kickPlayer(Socket socket, Player player) throws IOException, InvalidArguments, PlayerNotFound, LogInRequired{
		SupportingFunctions.sendCommand(socket.getOutputStream(), new String[]{"admin.kickPlayer", player.getName()});
		Parcel response = SupportingFunctions.getResponse(socket.getInputStream())[0];
		
		if (response.getStatus().equals("OK"))
			return true;
		else if (response.getStatus().equalsIgnoreCase("InvalidArguments"))
			throw new InvalidArguments();
		else if (response.getStatus().equalsIgnoreCase("PlayerNotFound"))
			throw new PlayerNotFound("Player, " + player.getName() + ", was not found.");
		else if (response.getStatus().equals("LogInRequired"))
			throw new LogInRequired();
		
		return false;
	}
	
	public static boolean unban(Socket socket, String type, String id) throws IOException, InvalidArguments, LogInRequired, NotFound {
		SupportingFunctions.sendCommand(socket.getOutputStream(), new String[]{"banList.remove", type, id});
		Parcel response = SupportingFunctions.getResponse(socket.getInputStream())[0];
		
		if (response.getStatus().equals("OK"))
			return true;
		else if (response.getStatus().equalsIgnoreCase("InvalidArguments"))
			throw new InvalidArguments();
		else if (response.getStatus().equalsIgnoreCase("NotFound"))
			throw new NotFound("Banned "+type+":"+id+" could not be found.");
		else if (response.getStatus().equals("LogInRequired"))
			throw new LogInRequired();
		
		return false;		
	}
	
	public static boolean clear(Socket socket) throws IOException, LogInRequired, InvalidArguments {
		SupportingFunctions.sendCommand(socket.getOutputStream(), new String[]{"banList.clear"});
		Parcel response = SupportingFunctions.getResponse(socket.getInputStream())[0];
		
		if (response.getStatus().equals("OK"))
			return true;
		else if (response.getStatus().equalsIgnoreCase("InvalidArguments"))
			throw new InvalidArguments();
		else if (response.getStatus().equals("LogInRequired"))
			throw new LogInRequired();
			
		return false;
	}
	
	public static boolean save(Socket socket) throws IOException, InvalidArguments, AccessError, LogInRequired {
		SupportingFunctions.sendCommand(socket.getOutputStream(), new String[]{"banList.save"});
		Parcel response = SupportingFunctions.getResponse(socket.getInputStream())[0];
		
		if (response.getStatus().equals("OK"))
			return true;
		else if (response.getStatus().equalsIgnoreCase("InvalidArguments"))
			throw new InvalidArguments();
		else if (response.getStatus().equalsIgnoreCase("AccessError"))
			throw new AccessError();
		else if (response.getStatus().equals("LogInRequired"))
			throw new LogInRequired();
			
		return false;
	}
	//Processes-----/

	//Getters-----\
	public String getTimeFormatted(){
		DecimalFormat format = new DecimalFormat("##");
		
		double time = Double.parseDouble(getDuration());
		int
			seconds = (int)(time%60),
			minutes = (int)(time/60%60),
			hours = (int)(time/3600%24),
			days = (int)(time/86400);
		
		return format.format(days) + "D " + format.format(hours) + "H " + format.format(minutes) + "M " + format.format(seconds) + "S";
	}
	
	public String getBanType() {
		return banType;
	}
	public String getId() {
		return id;
	}
	public String getIdType() {
		return idType;
	}
	public String getReason() {
		return reason;
	}
	public String getDuration() {
		return duration;
	}
	
	public void setBanType(String banType) {
		this.banType = banType;
	}
	public void setId(String id) {
		this.id = id;
	}
	public void setIdType(String idType) {
		this.idType = idType;
	}
	public void setReason(String reason) {
		this.reason = reason;
	}
	public void setDuration(String time) {
		this.duration = time;
	}
	//Getters-----/
}
